/**
 * 
 */
package com.mango.mstock;

import java.lang.ref.WeakReference;

import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.TextView;

import com.mango.common.model.Security;
import com.mango.common.util.CommonUtil;
import com.mango.mstock.base.MstockService;
import com.mango.mstock.support.MStockGlobalVars;
import com.mango.mstock.support.utils.MStockUtil;

/**
 * @author mango
 * 
 */
public class FloatingService extends MstockService implements Thread.UncaughtExceptionHandler {

	private static final String TAG = "FloatingService";

	private WindowManager mWindowManager;
	private WindowManager.LayoutParams mLayout;
	private FloatingWindow mFloatingWindow;
	
	private String code;
	private long startTime;
	
	private Handler updatePriceHandler;

	@Override
	public void onCreate() {
		super.onCreate();
		Log.i(TAG, "oncreate");
		
		createFloatView();
		updatePriceHandler = new UpdatePriceHandler(this);
		
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent == null) {
			Log.i(TAG, "onStartCommand receive null intent!");
			return super.onStartCommand(intent, flags, startId);
		}
		
		Log.i(TAG, "onStartCommand");
		code = intent.getStringExtra("code");
		showFloatingWindow();
		
		//在运行onStartCommand后service进程被kill后，那将保留在开始状态，但是不保留那些传入的intent。
		//不久后service就会再次尝试重新创建，因为保留在开始状态，在创建service后将保证调用onstartCommand。
		//如果没有传递任何开始命令给service，那将获取到null的intent
//		flags = START_STICKY;
		
		// 在运行onStartCommand后service进程被kill后，系统将会再次启动service，并传入最后一个intent给onstartCommand。
		// 直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent，
		// 那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent
		flags = START_REDELIVER_INTENT;
		
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.i(TAG, "onDestroy");
		super.onDestroy();
		if (mFloatingWindow != null) {
			closeFloatingWindow();
		}
	}

	private void createFloatView() {
		createWindowManager();
		createFloatingWindow();
	}

	public void showFloatingWindow() {
		mWindowManager.addView(mFloatingWindow, mLayout);
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					Bundle data = new Bundle();
					Security favorite = MStockUtil.getLatestMyFavorite(code);
					if (favorite == null) {
						CommonUtil.sleep(CommonUtil.REFRESH_INTERVAL_MILLISECS);
						continue;
					}
					data.putBoolean("isSuspended", favorite.getLatestPrice() == 0);
					if (!data.getBoolean("isSuspended")) {
						data.putString("name", favorite.getName());
						data.putString("yesterdayprice", String.valueOf(favorite.getYesterdayPrice()));
						data.putString("latestprice", String.valueOf(favorite.getLatestPriceStr()));
						data.putString("changepct", String.valueOf(favorite.getChangePct()));
						data.putInt("textcolor", 
								MStockUtil.getColorByLatestPrice(favorite.getYesterdayPrice(), favorite.getLatestPrice()));
					}
					
					Message msg = Message.obtain();
					msg.setData(data);
					updatePriceHandler.sendMessage(msg);

					CommonUtil.sleep(CommonUtil.REFRESH_INTERVAL_MILLISECS);
				}
			}
		}).start();
	}

	public void closeFloatingWindow() {
		mWindowManager.removeView(mFloatingWindow);
	}

	private void createWindowManager() {
		// get system window
		mWindowManager = (WindowManager) getApplication().getSystemService(
				Context.WINDOW_SERVICE);

		// 窗体的布局样式
		mLayout = new WindowManager.LayoutParams();

		// 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示): 2003
		mLayout.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

		// 设置窗体焦点及触摸：
		// FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
		mLayout.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

		// 设置显示的模式, 效果为背景透明
		mLayout.format = PixelFormat.RGBA_8888;

		// 设置对齐的方法
		mLayout.gravity = Gravity.START | Gravity.TOP;

		// 设置窗体宽度和高度
		mLayout.width = WindowManager.LayoutParams.WRAP_CONTENT;
		mLayout.height = WindowManager.LayoutParams.WRAP_CONTENT;

	}

	private void createFloatingWindow() {
		mFloatingWindow = new FloatingWindow(this);
		mFloatingWindow.setOnTouchListener(new OnTouchListener() {
			float mTouchStartX;
			float mTouchStartY;

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				v.performClick();
				
				// 获取相对屏幕的坐标，即以屏幕左上角为原点
				float x, y;
				x = event.getRawX();
				y = event.getRawY() - MStockGlobalVars.statusBarHeight;
				Log.i("startP", "startX" + mTouchStartX + "====startY"
						+ mTouchStartY);
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					// 获取相对View的坐标，即以此View左上角为原点
					mTouchStartX = event.getX();
					mTouchStartY = event.getY();
					Log.i("startP", "startX" + mTouchStartX + "====startY"
							+ mTouchStartY);
					long end = System.currentTimeMillis() - startTime;
					// 双击的间隔在 300ms以下
					if (end < 300) {
						closeFloatingWindow();
					}
					startTime = System.currentTimeMillis();
					break;
				case MotionEvent.ACTION_MOVE:
					// 更新浮动窗口位置参数
					mLayout.x = (int) (x - mTouchStartX);
					mLayout.y = (int) (y - mTouchStartY);
					mWindowManager.updateViewLayout(v, mLayout);
					break;
				case MotionEvent.ACTION_UP:

					// 更新浮动窗口位置参数
					mLayout.x = (int) (x - mTouchStartX);
					mLayout.y = (int) (y - mTouchStartY);
					mWindowManager.updateViewLayout(v, mLayout);

					// 可以在此记录最后一次的位置

					mTouchStartX = mTouchStartY = 0;
					break;
				}
				return true;
			}
		});
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void uncaughtException(Thread arg0, Throwable arg1) {
        Log.i(TAG, "uncaughtException   " + arg1);
	}
	
	static class UpdatePriceHandler extends Handler {
		//如果Handler是个内部类，那 么它也会保持它所在的外部类的引用。
		//为了避免泄露这个外部类，应该将Handler声明为static嵌套类，并且使用对外部类的弱应用
		WeakReference<FloatingService> pService;  
	     
		UpdatePriceHandler(FloatingService service) {  
        	pService = new WeakReference<FloatingService>(service);  
        }  

        @Override  
        public void handleMessage(Message msg) {  
        	FloatingService theService = pService.get();  
        	FloatingWindow pFloatingWindow = theService.mFloatingWindow;
        	
        	final TextView floatName = (TextView) pFloatingWindow
					.findViewById(R.id.float_name);
			final TextView floatPrice = (TextView) pFloatingWindow
					.findViewById(R.id.float_latestprice);
			final TextView floatChangePct = (TextView) pFloatingWindow
					.findViewById(R.id.float_changeppct);

			Bundle data = msg.getData();
			floatName.setText(data.getString("name"));
			if (data.getBoolean("isSuspended")) {
				floatPrice.setText("-停牌-");
				floatChangePct.setText("-停牌-");
			} else {
				floatPrice.setTextColor(data.getInt("textcolor"));
				floatPrice.setText(" " + data.getString("latestprice"));
				floatChangePct.setTextColor(data.getInt("textcolor"));
				floatChangePct.setText(" " + data.getString("changepct") + "%");
			}
        }  
	}

}
